﻿#if NETCORE

using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Server.HttpSys;

namespace Apewer.Web
{

    /// <summary>HTTP.sys 服务器。</summary>
    /// <remarks>
    /// <para>HTTP.sys 是仅在 Windows 上运行的适用于 ASP.NET Core 的 Web 服务器，提供了一些 Kestrel 不提供的功能。</para>
    /// <para>HTTP.sys 支持以下功能：<br />Windows 身份验证；<br />端口共享；<br />具有 SNI 的 HTTPS；<br />基于 TLS 的 HTTP/2（Windows 10 或更高版本）；<br />直接文件传输；<br />响应缓存；<br />WebSocket（Windows 8 或更高版本）。</para>
    /// </remarks>
    public class HttpSysServer<TStartup> : HttpSysServer where TStartup : AspNetCoreStartup
    {

        /// <summary>启动。</summary>
        public virtual void Run() => Run<TStartup>(false);

    }

    /// <summary>HTTP.sys 服务器。</summary>
    /// <remarks>
    /// <para>HTTP.sys 是仅在 Windows 上运行的适用于 ASP.NET Core 的 Web 服务器，提供了一些 Kestrel 不提供的功能。</para>
    /// <para>HTTP.sys 支持以下功能：<br />Windows 身份验证；<br />端口共享；<br />具有 SNI 的 HTTPS；<br />基于 TLS 的 HTTP/2（Windows 10 或更高版本）；<br />直接文件传输；<br />响应缓存；<br />WebSocket（Windows 8 或更高版本）。</para>
    /// </remarks>
    public class HttpSysServer : AspNetCoreServer
    {

        /// <summary>配置 WebHost 构建程序。</summary>
        protected override void Configure(IWebHostBuilder builder) => builder.UseHttpSys(Configure);

        /// <summary>配置 HTTP.sys 服务器。</summary>
        protected virtual void Configure(HttpSysOptions options)
        {
            // 同步 IO。
            options.AllowSynchronousIO = true;

            // 限制请求大小。
            options.MaxRequestBodySize = MaxBody;

            // 禁用内核缓存。
            options.EnableResponseCaching = false;

            // 认证。
            options.Authentication.Schemes = Microsoft.AspNetCore.Server.HttpSys.AuthenticationSchemes.None;
            options.Authentication.AllowAnonymous = true;

            // 配置端口和证书。
            var ip = "0.0.0.0";
            var port = Port;
            var certificate = Certificate;
            var protocol = certificate == null ? "http" : "https";
            var prefix = $"{protocol}://{ip}:{port}";
            options.UrlPrefixes.Add(prefix);
        }

        /// <summary>启动。</summary>
        public override void Run<T>() => Run<T>(false);

    }

}

#endif
